package org.papervision3d.core.geom
{
    import org.papervision3d.Papervision3D;
    import org.papervision3d.core.*;
    import org.papervision3d.core.proto.*;
    import org.papervision3d.core.geom.*;
    
    import org.papervision3d.objects.DisplayObject3D;
    
    import flash.geom.Matrix;
    import flash.display.*;
    import flash.utils.Dictionary;
    import flash.geom.Point;
    
    // The Face3D class lets you render linear textured triangles. It also supports solid colour fill and hairline outlines.
    public class Face3D
    {
        // An array of Vertex3D objects for the three vertices of the triangle.
        public var v0:Vertex3D;
        public var v1:Vertex3D;
        public var v2:Vertex3D;

        // A material id TODO
        public var materialname:String;

        public var drawtriangle:DrawTriangle;
        
        public var Zoffset : Number = 0;

        // An array of {x,y} objects for the corresponding UV pixel coordinates of each triangle vertex.
        public var uv0:NumberUV;
        public var uv1:NumberUV;
        public var uv2:NumberUV;
    
        // [read-only] A Boolean value that indicates that the face is visible, i.e. it's vertices are in front of the camera.
        public var visible:Boolean;
    
        // [read-only] Unique id of this instance.
        public var id:Number;
    
        public var texturemapping:TextureMapping;

        // The Face3D constructor lets you create linear textured or solid colour triangles.
        // @param    vertices    An array of Vertex3D objects for the three vertices of the triangle.
        // @param    material    A MaterialObject3D object that contains the material properties of the triangle.
        // @param    uv          An array of {x,y} objects for the corresponding UV pixel coordinates of each triangle vertex.
        public function Face3D(vertices:Array, materialname:String = null, uv:Array = null)
        {
            // Vertices
            this.v0 = vertices[0];
            this.v1 = vertices[1];
            this.v2 = vertices[2];
    
            // Material
            this.materialname = materialname;
            if (uv)
            {
                this.uv0 = uv[0];
                this.uv1 = uv[1];
                this.uv2 = uv[2];
            }

            this.id = _totalFaces++;
        }
    
        public function getMaterial(mesh:Mesh3D):MaterialObject3D
        {
            return (materialname && mesh.materials) ? mesh.materials.materialsByName[materialname] : mesh.material;
        }
        
        public function isFrontCamera() : Boolean {
        	return ( v0.projected.visible && v1.projected.visible && v2.projected.visible );
        }
        
        public function getCoordAtPoint( x : Number, y : Number ) : Vertex3D {
        	
        	var UV : Object = drawtriangle.UVatPoint(x,y);
        	//trace( UV.u, UV.v );
			var u : Number = UV.u;
			var v : Number = UV.v;
        	
        	var rX : Number = v0.x + ( v1.x - v0.x ) * v + ( v2.x - v0.x ) * u;
        	var rY : Number = v0.y + ( v1.y - v0.y ) * v + ( v2.y - v0.y ) * u;
        	var rZ : Number = v0.z + ( v1.z - v0.z ) * v + ( v2.z - v0.z ) * u;
        	
        	return new Vertex3D( rX, rY, rZ );
        }
        
       
        
        public function getNormal() : Number3D {
        	
        	var v0_x : Number = v2.x - v0.x;
        	var v0_y : Number = v2.y - v0.y;
        	var v0_z : Number = v2.z - v0.z;
        	var v1_x : Number = v1.x - v0.x;
        	var v1_y : Number = v1.y - v0.y;
        	var v1_z : Number = v1.z - v0.z;
        	
        	var res : Number3D = new Number3D(	(v0_y * v1_z) - (v0_z * v1_y) ,
					                            (v0_z * v1_x) - (v0_x * v1_z) ,
					                            (v0_x * v1_y) - (v0_y * v1_x));
			res.normalize();
        	return res;
        }

        private static var _totalFaces:Number = 0;
    }
}
